package net.butfly.bus.server.invoker.impl;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

import net.butfly.bus.Request;
import net.butfly.bus.Response;
import net.butfly.bus.context.Constants;
import net.butfly.bus.context.ContextManager;
import net.butfly.bus.exception.BusRuntimeException;
import net.butfly.bus.server.ServerConfig;
import net.butfly.bus.server.invoker.BeanWrapper;
import net.butfly.bus.server.invoker.Invoker;

public class LocalInvoker implements Invoker {

	private Map<String, BeanWrapper> registerBW;

	public LocalInvoker(Map<String, BeanWrapper> registerBW) {
		this.registerBW = registerBW;
	}

	public Response invoke(Request request, Response response) {
		String key = ServerConfig.getServiceKey(request.getTx(), request.getVersion());
		BeanWrapper bw = registerBW != null ? registerBW.get(key) : null;
		if (bw != null) {
			try {
				Object[] reqs = request.getArgs();
				for (Object o : reqs) {
					this.addInfo(o);
				}
				Object obj = bw.invoke(reqs);
				if (response != null) {
					response.setResult(obj);
				}
				return response;
			} catch (IllegalArgumentException e) {
				throw new BusRuntimeException(Constants.BusinessError.INVOKE_ERROR, "调用业务逻辑类 "
						+ bw.getBean().getClass() + " 的方法 " + bw.getMethod().getName() + " 时出现请求的参数个数或类型异常，请检查请求的参数列表",
						e);
			} catch (IllegalAccessException e) {
				throw new BusRuntimeException(Constants.BusinessError.INVOKE_ERROR, "业务逻辑类 " + bw.getBean().getClass()
						+ " 的方法 " + bw.getMethod().getName() + " 可能不是public类型", e);
			} catch (InvocationTargetException e) {
				Throwable tw = e.getTargetException();
				String message = tw.getMessage();
				message = message != null ? message : "业务逻辑类 " + bw.getBean().getClass() + " 的方法 "
						+ bw.getMethod().getName() + " 调用异常";
				String errorCode = Constants.BusinessError.INVOKE_ERROR;
				try {
					Method m = tw.getClass().getMethod("getCode");
					if (m != null) {
						errorCode = m.invoke(tw).toString();
					}
				} catch (Exception ex) {

				}
				throw new BusRuntimeException(errorCode, message, e.getTargetException());
			}
		} else {
			String keys = "";
			for (String k : registerBW.keySet()) {
				keys += k + ", ";
			}
			keys = !keys.equals("") ? keys.substring(0, keys.length() - 2) : keys;
			throw new BusRuntimeException(Constants.BusinessError.CONFIG_ERROR, "没有找到交易 " + key
					+ " 对应的业务逻辑对象(当前注册的交易如下:" + keys + ")");
		}
	}

	@Deprecated
	private void addInfo(Object req) {
		try {
			req.getClass().getMethod("setUserId", String.class)
					.invoke(req, ContextManager.getInstance().getAttribute("userId"));
		} catch (Exception e) {}

		try {
			req.getClass().getMethod("setIp", String.class)
					.invoke(req, ContextManager.getInstance().getAttribute("ip"));
		} catch (Exception e) {}
		try {
			Class<?> clazz = Class.forName("com.cmb.ewin.ebase.context.EWinContext$Channel");
			int channel = Integer.parseInt((String) ContextManager.getInstance().getAttribute("channel"));
			req.getClass().getMethod("setChannel", clazz)
					.invoke(req, clazz.getMethod("getByInt", int.class).invoke(null, channel));
		} catch (Exception e) {}
	}
}
